package com.fr.report.script.function;

import com.fr.base.core.DateUtils;
import com.fr.report.script.Function;
import com.fr.report.script.Function.Type;
import com.fr.report.script.NormalFunction;
import com.fr.report.script.Primitive;
import java.util.Date;
import java.util.GregorianCalendar;

public class DAYS360 extends NormalFunction
{
  public Object run(Object[] paramArrayOfObject)
  {
    if (paramArrayOfObject.length < 2)
      return Primitive.ERROR_NAME;
    Object[] arrayOfObject = { null, null, null };
    arrayOfObject[0] = paramArrayOfObject[0];
    arrayOfObject[1] = paramArrayOfObject[1];
    Date localDate1 = new Date();
    Date localDate2 = new Date();
    GregorianCalendar localGregorianCalendar1 = new GregorianCalendar();
    GregorianCalendar localGregorianCalendar2 = new GregorianCalendar();
    if (arrayOfObject[0] instanceof String)
      localDate1 = DateUtils.object2Date(arrayOfObject[0], false);
    if (arrayOfObject[1] instanceof String)
      localDate2 = DateUtils.object2Date(arrayOfObject[1], false);
    if (arrayOfObject[0] instanceof Number)
      localDate1.setTime((((Number)arrayOfObject[0]).longValue() - 25569L) * 1000L * 24L * 60L * 60L);
    if (arrayOfObject[1] instanceof Number)
      localDate2.setTime((((Number)arrayOfObject[1]).longValue() - 25569L) * 1000L * 24L * 60L * 60L);
    localGregorianCalendar1.setTime(localDate1);
    localGregorianCalendar2.setTime(localDate2);
    if (paramArrayOfObject.length < 1)
    {
      if (localGregorianCalendar1.get(5) == 31)
      {
        localDate1.setTime(localDate1.getTime() - 86400000L);
        localGregorianCalendar1.setTime(localDate1);
      }
      if ((localGregorianCalendar2.get(5) == 31) && (localGregorianCalendar1.get(5) < 30))
      {
        localDate2.setTime(localDate2.getTime() + 86400000L);
        localGregorianCalendar2.setTime(localDate2);
      }
      if ((localGregorianCalendar2.get(5) == 31) && (localGregorianCalendar1.get(5) == 30))
      {
        localDate2.setTime(localDate2.getTime() - 86400000L);
        localGregorianCalendar2.setTime(localDate2);
      }
    }
    else
    {
      arrayOfObject[2] = paramArrayOfObject[2];
      if ((arrayOfObject[2] instanceof String) && (arrayOfObject[2].toString().equals("FALSE")))
      {
        if (localGregorianCalendar1.get(5) == 31)
        {
          localDate1.setTime(localDate1.getTime() - 86400000L);
          localGregorianCalendar1.setTime(localDate1);
        }
        if ((localGregorianCalendar2.get(5) == 31) && (localGregorianCalendar1.get(5) < 30))
        {
          localDate2.setTime(localDate2.getTime() + 86400000L);
          localGregorianCalendar2.setTime(localDate2);
        }
        if ((localGregorianCalendar2.get(5) == 31) && (localGregorianCalendar1.get(5) == 30))
        {
          localDate2.setTime(localDate2.getTime() - 86400000L);
          localGregorianCalendar2.setTime(localDate2);
        }
      }
      if (arrayOfObject.toString().equals("TRUE"))
      {
        if (localGregorianCalendar1.get(5) == 31)
        {
          localDate1.setTime(localDate1.getTime() - 86400000L);
          localGregorianCalendar1.setTime(localDate1);
        }
        if (localGregorianCalendar2.get(5) == 31)
        {
          localDate2.setTime(localDate2.getTime() - 86400000L);
          localGregorianCalendar2.setTime(localDate2);
        }
      }
    }
    int i = 360 * (localGregorianCalendar2.get(1) - localGregorianCalendar1.get(1)) + 30 * (localGregorianCalendar2.get(2) - localGregorianCalendar1.get(2)) + localGregorianCalendar2.get(5) - localGregorianCalendar1.get(5);
    return new Integer(i);
  }

  public Function.Type getType()
  {
    return Function.DATETIME;
  }

  public String getCN()
  {
    return "DAYS360(start_date,end_date,method):按照一年 360 天的算法（每个月以 30 天计，一年共计 12 个月），\n返回两日期间相差的天数，这在会计计算中将会用到。如果财务系统是基于一年 12 个月，每月 30 天，\n可用此函数帮助计算支付款项。\nStart_date 和 end_date :是用于计算期间天数的起止日期。\nMethod : 它指定了在计算中是采用欧洲方法还是美国方法。\nMethod 定义 :\nFALSE或忽略    美国方法 (NASD)。如果起始日期是一个月的 31 号，则等于同月的 30 号。如果终止日期是一个月的\n31号，并且起始日期早于 30 号，则终止日期等于下一个月的 1 号，否则，终止日期等于本月的 30 号。\nTRUE           欧洲方法。无论是起始日期还是终止日期为一个月的 31 号，都将等于本月的 30 号。\n备注:\nFineReport将日期保存为系列数，一个系列数代表一个与之匹配的日期，以方便用户对日期进行数值式计算。\n在1900年日期系统中，FineReport电子表格将1900年1月1日保存为系列数2，将1900年1月2日保存为系列数3，\n将1900年1月3日保存为系列数4……依此类推。如在1900年日期系统，1998年1月1日存为系列数35796。\n示例:\nDAYS360(\"1998/1/30\", \"1998/2/1\") 等于 1";
  }

  public String getEN()
  {
    return "DAYS360(start_date,end_date,method): Returns the number of days between two dates based on a 360-day year (twelve 30-day months), which is used in some accounting calculations. Use this function to help compute payments if your accounting system is based on twelve 30-day months.\nStart_date and end_date are the two dates between which you want to know the number of days.\nMethod is a logical value that specifies whether to use the U.S. or European method in the calculation.\n\nMethod Definition:\nFALSE or omitted: U.S. (NASD) method. If the starting date is the 31st of a month, it becomes equal to the 30th of the same month. If the ending date is the 31st of a month and the starting date is earlier than the 30th of a month, the ending date becomes equal to the 1st of the next month; otherwise the ending date becomes equal to the 30th of the same month.\nTRUE: European method. Starting dates and ending dates that occur on the 31st of a month become equal to the 30th of the same month.\n\nRemarks:\n   FineReport stores dates as sequential serial numbers so they can be used in calculations. FineReport stores January 1, 1900 as serial number 2，January 2, 1900 as 3，\nJanuary 3, 1900 as 4, and so on, so January 1, 1998 as serial number 35796.\n\nExample:\n   DAYS360(\"1998/1/30\", \"1998/2/1\") = 1";
  }
}